/*
 * np_time.h
 *
 *  Created on: Nov 22, 2010
 *      Author: jeff_zheng
 *   Copyright: NetPerform Technology
 */

#ifndef NP_TIME_H_
#define NP_TIME_H_

#include <time.h>
#include <sys/time.h>

#ifdef __cplusplus
extern "C" {
#endif

static inline int np_str_from_time(const uint64_t time, char* result, size_t length)
{
	struct tm tm;
	gmtime_r((time_t*)&time, &tm);

	result[0]=0;

	size_t written = strftime(result, length, "%F %T", &tm);
	if (written == 0)
		return -1;
	if (written >= length)
		return -1;
	return 0;
}

static inline void np_tsc32_read(uint32_t* tsc)
{
__asm__ __volatile__("rdtsc" : "=a" (*tsc) : : "edx");
}

static inline void np_tsc64_read(uint64_t* tsc64)
{
     unsigned int __a,__d;
     __asm__ __volatile__("rdtsc" : "=a" (__a), "=d" (__d));
     *tsc64 = ((unsigned long)__a) | (((unsigned long)__d)<<32);
}

static inline uint32_t np_tsc32_get(void)
{
    uint32_t tsc;
    np_tsc32_read(&tsc);
    return tsc;
}

extern uint64_t g_np_time_ns;
extern uint64_t g_np_time_us;
extern uint64_t g_np_time_ms;
extern uint64_t g_np_time_sec;
static inline uint64_t np_time_get_time()
{
	return g_np_time_sec;
}

static inline uint64_t np_time_get_ns()
{
	return g_np_time_ns;
}
static inline uint64_t np_time_get_us()
{
	return g_np_time_us;
}
static inline uint64_t np_time_get_ms()
{
	return g_np_time_ms;
}

typedef struct np_time_us_s
{
	union
	{
		struct
		{//little endian
			uint32_t us;
			uint32_t sec;
		}tv32;
		uint64_t tv64;
	}v;
}np_time_us;

static inline void np_time_get_time_us(np_time_us* us)
{
    struct timeval tv;

    gettimeofday(&tv, NULL);
    us->v.tv32.sec = tv.tv_sec;
    us->v.tv32.us  = tv.tv_usec;
}



extern void np_time_sleep(uint32_t sec, uint32_t nanosec);


extern int np_time_lib_init();


/*\@}*/


#ifdef __cplusplus
}
#endif


#endif /* NP_TIME_H_ */
